package org.yu.api.register.data;

import com.google.common.collect.Multimap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.DataProvider;
import net.minecraft.data.HashCache;
import org.apache.commons.lang3.text.translate.JavaUnicodeEscaper;
import org.jetbrains.annotations.NotNull;
import org.yu.api.register.TranslationBean;


import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;

public class LazyLangProvider implements DataProvider {
    private static final Gson GSON = (new GsonBuilder()).setPrettyPrinting().disableHtmlEscaping().create();
    private final DataGenerator gen;
    private final String modid;
    private final Multimap<String, Supplier<TranslationBean>> langMultiMap;

    public LazyLangProvider(DataGenerator gen, String modid, Multimap<String, Supplier<TranslationBean>> langMultiMap) {
        this.gen = gen;
        this.modid = modid;
        this.langMultiMap = langMultiMap;
    }

    @Override
    public void run(@NotNull HashCache pCache) {
        langMultiMap.keySet().forEach(key -> {
            Map<String, String> data = new HashMap<>();
            langMultiMap.get(key).forEach(translateBeanSupplier -> {
                TranslationBean translationBean = translateBeanSupplier.get();
                data.put(translationBean.key(), translationBean.value());
            });
            try {
                save(pCache, data, this.gen.getOutputFolder().resolve("assets/" + modid + "/lang/" + key + ".json"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    private void save(HashCache cache, Object object, Path target) throws IOException {
        String data = GSON.toJson(object);
        data = JavaUnicodeEscaper.outsideOf(0, 0x7f).translate(data); // Escape unicode after the fact so that it's not double escaped by GSON
        String hash = DataProvider.SHA1.hashUnencodedChars(data).toString();
        if (!Objects.equals(cache.getHash(target), hash) || !Files.exists(target)) {
            Files.createDirectories(target.getParent());

            try (BufferedWriter bufferedwriter = Files.newBufferedWriter(target)) {
                bufferedwriter.write(data);
            }
        }

        cache.putNew(target, hash);
    }

    @Override
    public String getName() {
        return "LazyLangProvider For " + modid;
    }
}
